package com.zjh.document.controller;


import com.zjh.common.entity.Response;
import com.zjh.document.entity.DTO.FileObject;
import com.zjh.document.entity.QTO.SystemFIleQto1;
import com.zjh.document.entity.VO.MinioFileInfoVO;
import com.zjh.document.service.impl.MinIOService;
import com.zjh.document.service.impl.MinioUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/documentManager/file")
@Slf4j
public class MinioController {

    @Autowired
    MinIOService minIOService;
    @Value("${minio.bucket}")
    private String bucket;
    @Resource
    private MinioUtils minioUtils;

    /**
     * 获取所有BucketName
     */
    @GetMapping("/getBucketList")
    public Response<List<String>> getBucketList() {
        return Response.success(minIOService.getAllBucket());
    }

    /**
     * newFile
     */

    @PostMapping("/newFile")
    public Response<String> newFile(@RequestParam String fileName) throws Exception {
        String filePureName = fileName.split("\\.")[0];
        String fileType = fileName.split("\\.")[1];
        minIOService.newFileAndUploadFileToMinio(filePureName, fileType);

        return Response.success(minioUtils.getPresignedObjectUrl(bucket, fileName));
    }

    @PostMapping("/moveFile")
    public Response<?> moveFile(@RequestBody SystemFIleQto1 qto1) {
        boolean b = minIOService.moveFileInMinio(qto1.getSourceFilePath(), qto1.getTargetFolderPath());
        if (b) {
            return Response.success();
        } else {
            return Response.error("移动文件失败");
        }
    }

    @PostMapping("/moveFolder")
    public Response<?> moveFolder(@RequestBody SystemFIleQto1 qto1) {
        boolean b = minIOService.transferFolder(qto1.getSourceFilePath(), qto1.getTargetFolderPath(), null);
        if (b) {
            return Response.success();
        } else {
            return Response.error("移动文件夹失败");
        }
    }

    /**
     * 新建文件夹
     */
    @PostMapping("/newFolder")
    public Response<String> newFolder(@RequestParam String folderName) throws Exception {
        minioUtils.newFolder(folderName + "/", bucket);
        return Response.success(folderName);
    }

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public Response<String> upload(@RequestParam(value = "path") String path,
                                   @RequestParam("file") MultipartFile file,
                                   @RequestParam(value = "fileName", required = false) String fileName) {

        String name = file.getOriginalFilename();
        boolean res;
        String newPath = path + name;

        // 如果指定了文件名，则使用指定名称
        if (StringUtils.isNotBlank(fileName)) {
            newPath = path + fileName;
        }

        res = minIOService.uploadFile(bucket, file, newPath);
        if (res) {
            return Response.success("上传文件" + name + "到 " + path + " 成功");
        } else {
            return Response.error("上传文件失败");
        }
    }

    @PostMapping("/uploadMulti")
    public Response<List<String>> uploadToMinio(
            @RequestParam(value = "path", required = false) String path,
            @RequestParam("files") MultipartFile[] files) {

        try {
            List<String> uploadedFiles = new ArrayList<>();

            for (MultipartFile file : files) {
                // 生成唯一文件名
                String originalFilename = file.getOriginalFilename();
                String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
                String pureName = originalFilename.substring(0, originalFilename.lastIndexOf("."));

                String uniqueFileName = pureName + "-" + UUID.randomUUID() + fileExtension;

                // 构建存储路径
                String objectName = (path != null && !path.isEmpty()) ? path + "/" + uniqueFileName : uniqueFileName;

                minIOService.uploadFile(bucket, file, objectName);

                uploadedFiles.add(objectName);
            }

            return Response.success("文件上传成功", uploadedFiles);
        } catch (Exception e) {
            return Response.error("文件上传失败: " + e.getMessage());
        }
    }
    /**
     * 上传文件到指定Bucket
     */
    @PostMapping("/upload2")
    public String upload(@RequestParam("fileName") String fileName, @RequestParam("bucketName") String bucketName, @RequestParam("file") MultipartFile file) {
        minIOService.existBucket(bucketName);
        boolean b = minIOService.uploadFile(bucketName, file, fileName);
        if (b) {
            return "upload " + fileName + " success";
        } else {
            return "upload " + fileName + "  failed";
        }
    }

    /**
     * 删除文件
     */
    @PostMapping("/delete")
    public Response delete(@RequestParam("path") String path) throws Exception {
        boolean b = minIOService.delete(bucket, path);
        if (b) {
            return Response.success();
        } else {
            return Response.error("删除失败");
        }
    }

    /**
     * 删除文件夹
     */
    @PostMapping("/deleteFolder")
    public Response deleteFolder(@RequestParam("path") String path) throws Exception {
        minIOService.deleteFolder(bucket, path);
        return Response.success();

    }

    /**
     * 批量删除文件
     */
    @PostMapping("/batchDelete")
    public Response batchDelete(@RequestBody List<String> path) throws Exception {
        boolean b = minIOService.batchDelete(bucket, path);
        if (b) {
            return Response.success();
        } else {
            return Response.error("删除失败");
        }

    }

    /**
     * 获取一个Bucket 中的所有文件
     */
    @GetMapping("/getAllFiles")
    public Response<List<MinioFileInfoVO>> getAllFiles(@RequestParam("bucketName") String bucketName) {
        List<MinioFileInfoVO> res = minIOService.getAllFilesByBucketName(bucketName);

        return Response.success(res);
    }


    @GetMapping("/getAllfileByFolder")
    public Response<List<FileObject>> listFilesAndFolders(String folderPath) {

        return Response.success(minIOService.listFilesAndFolders(folderPath));
    }

    /**
     * 获取文件外链
     *
     * @param fileName
     * @return
     */
    @GetMapping("/url")
    public Response<String> getPresignedObjectUrl(@RequestParam("fileName") String fileName) {
        return Response.success(minioUtils.getPresignedObjectUrl(bucket, fileName));
    }

    /**
     * 获取文件外链
     *
     * @param fileName
     * @return
     */
    @GetMapping("/fileInfo")
    public Response<String> getFileInfo(@RequestParam("fileName") String fileName) {
        return Response.success(minioUtils.getFileContentType(bucket, fileName));
    }


    /**
     * 文件下载
     *
     * @param fileName
     * @param response
     */
    @GetMapping("/download")
    public void download(@RequestParam("fileName") String fileName, HttpServletResponse response) {
        try {
            InputStream fileInputStream = minioUtils.getObject(bucket, fileName);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            String contextType = minioUtils.getFileContentType(bucket, fileName);
            response.setContentType(contextType);
            response.setCharacterEncoding("UTF-8");
            IOUtils.copy(fileInputStream, response.getOutputStream());

        } catch (Exception e) {
            log.error("下载失败");
        }
    }

    @GetMapping("/preview")
    public void preview(@RequestParam("fileName") String fileName, HttpServletResponse response) {
        try {
            InputStream fileInputStream = minioUtils.getObject(bucket, fileName);
            response.setContentType("application/xml"); // 非 attachment
            response.setCharacterEncoding("UTF-8");

            String contextType = minioUtils.getFileContentType(bucket, fileName);
            response.setContentType(contextType);
            response.setCharacterEncoding("UTF-8");
            IOUtils.copy(fileInputStream, response.getOutputStream());

        } catch (Exception e) {
            log.error("下载失败");
        }
    }
    @GetMapping("/getText")
    public Response<String> getText(@RequestParam String fileName) throws Exception {

        String res = minIOService.readTextFile(bucket, fileName);

        return Response.success(res);
    }

    @PostMapping("/renameFile")
    public Response<?> renameFile(
            @RequestParam String oldName,
            @RequestParam String newName) {
        try {
            minIOService.renameFile(oldName, newName);
            return Response.success("文件重命名成功");
        } catch (Exception e) {
            return Response.error("文件重命名失败: " + e.getMessage());
        }
    }

    @PostMapping("/renameFolder")
    public Response<?> renameFolder(
            @RequestParam String oldPath,
            @RequestParam String newPath) {
        try {
            minIOService.renameFolder(oldPath, newPath);
            return Response.success("文件夹重命名成功");
        } catch (Exception e) {
            return Response.error("文件夹重命名失败: " + e.getMessage());
        }
    }
}